package com.wy2cloud.sample.zuulandauthserver.config;

import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import com.wy2cloud.sample.zuulandauthserver.service.UserDetailsServiceImpl;

import redis.clients.jedis.JedisPoolConfig;

/**
 * 配置client信息，以及源码中自带路径（如/oauth/check_token,默认是关闭的）的设置
 */
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
	
	@Autowired
	private RedisProperties redisProperties;
	
    @Autowired
    private AuthenticationManager authenticationManager;
    
//    @Autowired
//    private RedisConnectionFactory connectionFactory;

    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    
    
    private RedisConnectionFactory connectionFactory() {
		JedisConnectionFactory jedis = new JedisConnectionFactory();
		jedis.setHostName(redisProperties.getHost());
		jedis.setPort(redisProperties.getPort());
		if (!StringUtils.isEmpty(redisProperties.getPassword())) {
			jedis.setPassword(redisProperties.getPassword());
		}
		jedis.setDatabase(3);
		
		jedis.setPoolConfig(poolCofig(redisProperties.getPool().getMaxActive(), redisProperties.getPool().getMaxIdle(), redisProperties.getPool().getMaxWait()));
		// 初始化连接pool
		jedis.afterPropertiesSet();
		RedisConnectionFactory factory = jedis;

		return factory;
	}

	private JedisPoolConfig poolCofig(int maxIdle, int maxTotal,long maxWaitMillis) {
		JedisPoolConfig poolCofig = new JedisPoolConfig();
		poolCofig.setMaxIdle(maxIdle);
		poolCofig.setMaxIdle(maxIdle);
		poolCofig.setMaxTotal(maxTotal);
		poolCofig.setMaxWaitMillis(maxWaitMillis);
		return poolCofig;
	}

    @Bean
    public RedisTokenStore tokenStore() {
        return new RedisTokenStore(connectionFactory());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
        .userDetailsService(userDetailsService)
        .tokenStore(tokenStore());

        // 配置TokenServices参数
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(endpoints.getTokenStore());
        tokenServices.setSupportRefreshToken(false);
        tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
        tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
        tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30)); // 30天
        endpoints.tokenServices(tokenServices);

    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    	
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
        //oauthServer.checkTokenAccess("permitAll()"); //.checkTokenAccess("isAuthenticated()");
        oauthServer.allowFormAuthenticationForClients();
    }

    @Bean
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        /*ClientDetailsService clientDetailsService = clientDetails();
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId("client");
        String str = clientDetails.getClientSecret();
        System.out.println("===================client: " + str);*/
        
        clients.withClientDetails(clientDetails());
//		clients.inMemory().withClient("client").secret("client").authorizedGrantTypes("authorization_code", "password")
//				.scopes("app");
    }

    
}
